﻿using System.Collections.ObjectModel;
using System.IO;
using hDualPaneLib.Model;

namespace hDualPaneLib.Controller
{
    /// <summary>
    /// File manager
    /// </summary>
    public class FileManager
    {
        //Left list
        ObservableCollection<ItemInfo> _leftList = new ObservableCollection<ItemInfo>();
        //Right list
        ObservableCollection<ItemInfo> _rightList = new ObservableCollection<ItemInfo>();
        //Current path of left pane
        private string _leftPath = "";
        public string LeftPath { get { return _leftPath; } }
        //Current path of right pane
        private string _rightPath = "";
        public string RightPath { get { return _rightPath; } }
        //Current working pane, true = left false = right
        private bool _currentPane;
        public bool CurrentPane
        {
            get { return _currentPane; }
            set { _currentPane = value; }
        }

        private int _leftIndex = 0;

        public int LeftIndex
        {
            get { return _leftIndex; }
            set { _leftIndex = value; }
        }
        private int _rightIndex = 0;

        public int RightIndex
        {
            get { return _rightIndex; }
        }


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="fullPath"></param>
        public FileManager(string fullPath)
        {
            //Start up the pane
            _leftPath = fullPath;
            _rightPath = fullPath;
            _currentPane = true;
            updateItemList(DataTypeHelper.ManagerPanel.LeftPane);
            updateItemList(DataTypeHelper.ManagerPanel.RightPane);
        }

        /// <summary>
        /// Update the content of specified pane
        /// </summary>
        /// <param name="pane">Left or Right pane</param>
        public void updateItemList(DataTypeHelper.ManagerPanel pane)
        {
            //Reference list, could be either left or right list
            ObservableCollection<ItemInfo> list = new ObservableCollection<ItemInfo>();
            //Reference path, could be either left or right path
            string fullPath = "";
            //Left or right?
            if (pane == DataTypeHelper.ManagerPanel.LeftPane)
            {
                list = _leftList;
                fullPath = _leftPath;
            }
            else
            {
                list = _rightList;
                fullPath = _rightPath;
            }
            //Clear old list
            list.Clear();
            //Directories list
            string[] dirsList = Directory.GetDirectories(fullPath);
            //File list
            string[] filesList = Directory.GetFiles(fullPath);
            //"Go Back" item on top of the list
            list.Add(new ItemInfo
            {
                Name = "..",
                Extension = "<BACK>",
                Size = -1,
                Selected = true,
                Pane = pane
            });

            //List directories
            for (int i = 0; i < dirsList.Length; i++)
            {
                ItemInfo dir = new ItemInfo();
                dir.Name = Path.GetFileName(dirsList[i]);
                dir.Extension = "<DIR>";
                dir.Pane = pane;
                //Negative size because this is a directory
                dir.Size = -1;
                //Add the dir to the list
                list.Add(dir);

            }

            //List files
            for (int i = 0; i < filesList.Length; i++)
            {
                ItemInfo file = new ItemInfo();
                FileInfo info = new FileInfo(filesList[i]);

                file.Name = Path.GetFileNameWithoutExtension(filesList[i]);
                file.Extension = Path.GetExtension(filesList[i]).ToLower();
                file.Size = info.Length;
                file.Pane = pane;
                //Add the file to the list
                list.Add(file);
            }
        }

        /// <summary>
        /// List of items to be displayed on left pane
        /// </summary>
        public ObservableCollection<ItemInfo> LeftList
        {
            get { return _leftList; }
        }

        /// <summary>
        /// List of items to be displayed on right pane
        /// </summary>
        public ObservableCollection<ItemInfo> RightList
        {
            get { return _rightList; }
        }

        /// <summary>
        /// Process the selected file/folder
        /// </summary>
        /// <param name="info">File/folder info</param>
        /// <param name="pane">On which pane? Left or Right</param>
        public void processItem(ItemInfo info, DataTypeHelper.ManagerPanel pane)
        {
            //Folder is selected
            if (info.Extension.Equals("<DIR>"))
            {
                //Left or Right pane
                if (pane == DataTypeHelper.ManagerPanel.LeftPane)
                {

                    //New path = Old path + Selected path
                    _leftPath = Path.Combine(_leftPath, info.Name);
                    _leftIndex = 0;
                    updateItemList(DataTypeHelper.ManagerPanel.LeftPane);
                }
                else
                {
                    _rightPath = Path.Combine(_rightPath, info.Name);
                    _rightIndex = 0;
                    updateItemList(DataTypeHelper.ManagerPanel.RightPane);
                }
            }

            //The Back "button" is selected
            else if (info.Extension.Equals("<BACK>"))
            {
                navigateBack(pane);
            }
        }

        /// <summary>
        /// Go back/up one level of the directory tree
        /// </summary>
        /// <param name="pane">Left or Right?</param>
        private void navigateBack(DataTypeHelper.ManagerPanel pane)
        {
            if (pane == DataTypeHelper.ManagerPanel.LeftPane)
            {
                //Don't go back if reach root directory
                if (!_leftPath.Equals(Directory.GetDirectoryRoot(_leftPath)))
                {
                    //Update the path
                    _leftPath = Directory.GetParent(_leftPath).FullName;
                    //Update the pane
                    updateItemList(DataTypeHelper.ManagerPanel.LeftPane);
                }
            }

            else
            {
                if (!_rightPath.Equals(Directory.GetDirectoryRoot(_rightPath)))
                {
                    _rightPath = Directory.GetParent(_rightPath).FullName;
                    updateItemList(DataTypeHelper.ManagerPanel.RightPane);
                }
            }
        }

        /// <summary>
        /// Swap/Focus working panel
        /// </summary>
        /// <param name="pane">Left or right pane</param>
        /// <param name="nextPaneIndex"></param>
        public void focusPane(DataTypeHelper.ManagerPanel pane, int nextPaneIndex)
        {
            if (pane == DataTypeHelper.ManagerPanel.LeftPane)
            {
                _rightIndex = nextPaneIndex;
            }
            else
            {
                _leftIndex = nextPaneIndex;
            }
        }
    }
}
